package com.kggs.springsnmp.utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.DefaultPDUFactory;
import org.snmp4j.util.TableEvent;
import org.snmp4j.util.TableUtils;
/**
 * 注：双方都启动了snmp协议的情况下才起作用。snmp4j架包请自行到官网下载
 * @author jzj
 * @date 2020/7/30 15:23
 */
public class SnmpUtil {
  public static final int DEFAULT_VERSION = SnmpConstants.version2c;
  public static final String DEFAULT_PROTOCOL = "udp";
  public static final int DEFAULT_PORT = 161;
  public static final int DEFAULT_RETRY = 3;
  public static final int DEFAULT_TIMEOUT = 8000;

  public static void main(String[] args) {
    // creatSnmp("47.94.207.62");
    System.out.println(collectMemory2("10.20.2.139"));
    // System.out.println(collectCPU("10.20.2.139"));
  }

  /**
   * 创建snmp
   *
   * @description:
   * @param ip
   */
  public static CommunityTarget creatSnmp(String ip) {
    CommunityTarget target = new CommunityTarget();
    // 社区名称
    target.setCommunity(new OctetString("public"));
    // 连接次数
    target.setRetries(DEFAULT_RETRY);
    // 监控的主机
    target.setAddress(
        GenericAddress.parse("" + DEFAULT_PROTOCOL + ":" + ip + "/" + DEFAULT_PORT + ""));
    target.setTimeout(DEFAULT_TIMEOUT);
    target.setVersion(DEFAULT_VERSION);
    return target;
  }

  /**
   * 获取内存相关信息(算磁盘缓存大小)
   *
   * @description:
   * @return: java.lang.String
   */
  public static String collectMemory(String ip) {
    CommunityTarget target = SnmpUtil.creatSnmp(ip);
    Snmp snmp = null;
    double memory = 0f;
    // type 存储单元类型
    // descr
    // unit 存储单元大小
    // size 总存储单元数
    String[] oids = {
      "1.3.6.1.2.1.25.2.3.1.2",
      "1.3.6.1.2.1.25.2.3.1.3",
      "1.3.6.1.2.1.25.2.3.1.4",
      "1.3.6.1.2.1.25.2.3.1.5",
      "1.3.6.1.2.1.25.2.3.1.6"
    };
    // used 使用存储单元数;
    // 物理存储
    String physicalMemoryOid = "1.3.6.1.2.1.25.2.1.2";
    try {
      // 创建snmp
      // 监听消息
      DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
      snmp = new Snmp(transport);
      snmp.listen();

      TableUtils tableUtils = new TableUtils(snmp, new DefaultPDUFactory(PDU.GETBULK));
      OID[] columns = new OID[oids.length];
      for (int i = 0; i < oids.length; i++) {
        columns[i] = new OID(oids[i]);
      }
      List<TableEvent> list = tableUtils.getTable(target, columns, null, null);
      for (TableEvent event : list) {
        VariableBinding[] values = event.getColumns();
        if (values == null) {
          continue;
        }
        // int unit = Integer.parseInt(values[2].getVariable().toString());unit 存储单元大小
        // size 总存储单元数
        long totalSize = Long.parseLong(values[3].getVariable().toString());
        // used 使用存储单元数（算磁盘缓存大小）
        long usedSize = Long.parseLong(values[4].getVariable().toString());
        String oid = values[0].getVariable().toString();
        if (physicalMemoryOid.equals(oid)) {
          memory = (usedSize * 100 / totalSize);
          break;
        }
      }

    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (snmp != null) {
        try {
          snmp.close();
        } catch (IOException ex1) {
          snmp = null;
        }
      }
    }
    return String.format("%.2f", memory);
  }

  /**
   * 获取内存相关信息
   *
   * @param ip
   * @return
   */
  public static String collectMemory2(String ip) {
    CommunityTarget target = SnmpUtil.creatSnmp(ip);
    Snmp snmp = null;
    double memory = 0f;
    // 内存总大小
    // descr
    // unit 存储单元大小
    // size 总存储单元数
    String[] oids = {
      "1.3.6.1.4.1.2021.4.5",
      "1.3.6.1.4.1.2021.4.6",
      "1.3.6.1.4.1.2021.4.13",
      "1.3.6.1.4.1.2021.4.14",
      "1.3.6.1.4.1.2021.4.15"
    };
    // used 使用存储单元数;物理存储
    String physicalMemoryOid = "1.3.6.1.2.1.25.2.1.2";
    try {
      // 创建snmp
      // 监听消息
      DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
      snmp = new Snmp(transport);
      snmp.listen();

      TableUtils tableUtils = new TableUtils(snmp, new DefaultPDUFactory(PDU.GETBULK));
      OID[] columns = new OID[oids.length];
      for (int i = 0; i < oids.length; i++) {
        columns[i] = new OID(oids[i]);
      }
      List<TableEvent> list = tableUtils.getTable(target, columns, null, null);
      for (TableEvent event : list) {
        VariableBinding[] values = event.getColumns();
        if (values == null) {
          continue;
        }
        // size 总存储单元数
        double totalSize = Long.parseLong(values[0].getVariable().toString());
        // used 空闲
        double freeSize = Long.parseLong(values[1].getVariable().toString());
        // 磁盘缓存大小
        double availableSize = Long.parseLong(values[4].getVariable().toString());
        double bufferSize = Long.parseLong(values[3].getVariable().toString());
        memory = (totalSize - freeSize - availableSize - bufferSize) / totalSize * 100;
        break;
      }

    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (snmp != null) {
        try {
          snmp.close();
        } catch (IOException ex1) {
          snmp = null;
        }
      }
    }
    return String.format("%.2f", memory);
  }
  /**
   * 获取cpu使用率
   *
   * @description:
   * @param ip
   * @return: java.lang.String
   */
  public static List<String> collectCpu(String ip) {
    CommunityTarget target = SnmpUtil.creatSnmp(ip);
    Snmp snmp = null;
    String memory = "";

    List<String> cpu = new ArrayList<>();
    String[] oids = {"1.3.6.1.2.1.25.3.3.1.2"};
    try {
      DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
      // 创建snmp
      // 监听消息
      snmp = new Snmp(transport);
      snmp.listen();

      TableUtils tableUtils = new TableUtils(snmp, new DefaultPDUFactory(PDU.GETBULK));
      OID[] columns = new OID[oids.length];
      for (int i = 0; i < oids.length; i++) {
        columns[i] = new OID(oids[i]);
      }
      List<TableEvent> list = tableUtils.getTable(target, columns, null, null);
      double percentage = 0f;
      int count = 0;
      for (TableEvent event : list) {
        VariableBinding[] values = event.getColumns();
        if (values != null) {
          if (Integer.parseInt(values[0].getVariable().toString()) > 0) {
            count++;
          }
        }
        percentage += Double.parseDouble(values[0].getVariable().toString());
      }
      cpu.add(String.format("%.2f", percentage / list.size()));
      cpu.add(list.size() + "");
      cpu.add(count + "");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (snmp != null) {
        try {
          snmp.close();
        } catch (IOException ex1) {
          snmp = null;
        }
      }
    }
    return cpu;
  }



}
